﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;

namespace NetTopologySuite.LinearReferencing
{
	public class LinearGeometryBuilder
	{
		public LinearGeometryBuilder(IGeometryFactory geomFact)
		{
			this._geomFact = geomFact;
		}

		public bool FixInvalidLines { get; set; }

		public bool IgnoreInvalidLines { get; set; }

		public void Add(Coordinate pt)
		{
			this.Add(pt, true);
		}

		public void Add(Coordinate pt, bool allowRepeatedPoints)
		{
			if (this._coordList == null)
			{
				this._coordList = new CoordinateList();
			}
			this._coordList.Add(pt, allowRepeatedPoints);
			this._lastPt = pt;
		}

		public Coordinate LastCoordinate
		{
			get
			{
				return this._lastPt;
			}
		}

		public void EndLine()
		{
			if (this._coordList == null)
			{
				return;
			}
			if (this.IgnoreInvalidLines && this._coordList.Count < 2)
			{
				this._coordList = null;
				return;
			}
			Coordinate[] array = this._coordList.ToCoordinateArray();
			Coordinate[] coordinates = array;
			if (this.FixInvalidLines)
			{
				coordinates = LinearGeometryBuilder.ValidCoordinateSequence(array);
			}
			this._coordList = null;
			ILineString lineString = null;
			try
			{
				lineString = this._geomFact.CreateLineString(coordinates);
			}
			catch (ArgumentException ex)
			{
				if (!this.IgnoreInvalidLines)
				{
					throw ex;
				}
			}
			if (lineString != null)
			{
				this._lines.Add(lineString);
			}
		}

		private static Coordinate[] ValidCoordinateSequence(Coordinate[] pts)
		{
			if (pts.Length >= 2)
			{
				return pts;
			}
			return new Coordinate[]
			{
				pts[0],
				pts[0]
			};
		}

		public IGeometry GetGeometry()
		{
			this.EndLine();
			return this._geomFact.BuildGeometry(this._lines);
		}

		private readonly IGeometryFactory _geomFact;

		private readonly List<IGeometry> _lines = new List<IGeometry>();

		private CoordinateList _coordList;

		private Coordinate _lastPt;
	}
}
